package com.myway.service.order;

import com.myway.dto.flight.DTOSegment;
import com.myway.dto.ics.DTOCabinCounter;
import com.myway.dto.order.DTOPaxSegment;
import com.myway.dto.order.domain.Inventory;
import com.myway.dto.order.domain.SegmentStatus;
import com.myway.dto.vo.FlySegmentVo;
import com.myway.utils.DateUtils;
import com.myway.utils.FlightNoUtils;
import com.myway.pojo.FlySegment;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;


public class SegmentUtils {
	
	private final static Logger log = Logger.getLogger(SegmentUtils.class);
	
	private SegmentUtils() {
	}
	
	/**
	 * Return list of cabin counter for the given passenger segment list. For example:
	 * 根据旅客航段列表数据，返回客舱数量集合信息
	 * <pre>
	 *     HAK-PEK    F    3
	 *     HAK-PEK    Y    15
	 *     PEK-HAK    Y    25
	 * </pre>
	 * 
	 * @param segList
	 * @param paxSegList
	 *            List of passenger segments. Passenger segment of an infant should not be included in this list as it will not
	 *            occupy any seat. 婴儿客运段将不包括在此名单，因为它不会占用任何座位。
	 * @param inventory
	 *            Inventory
	 * @return
	 */
	public static List<DTOCabinCounter> constructCabinCounter(final List<com.myway.dto.order.DTOSegment> segList,
															  final List<DTOPaxSegment> paxSegList, final Inventory inventory) {
		log.debug("Constructing cabin counter for " + inventory);
		List<DTOCabinCounter> cabinCounterList = new ArrayList<DTOCabinCounter>();
		//每个航段设置库存
		// Construct list of DTOCabinCounter objects for every segments from the given inventory
		for (com.myway.dto.order.DTOSegment seg : segList) {
			//私有库存
			if (inventory == seg.getInventory()) { // Segment is from the given inventory
				DTOCabinCounter cabinCounter = new DTOCabinCounter();
				cabinCounter.setSegment(SegmentUtils.convertToFlightSegment(seg));
				cabinCounter.setCabin(seg.getCabinClass());
				
				for (DTOPaxSegment paxSeg : paxSegList) {
					if (isSameSegment(paxSeg, seg)) {
						if (SegmentStatus.RR == paxSeg.getStatus()) {
							// Increment sold count  增量售出数
							cabinCounter.setSoldCount(cabinCounter.getSoldCount() + 1);
						} else if (SegmentStatus.HK == paxSeg.getStatus()) {
							// Increment reserved count 增量保留计数
							cabinCounter.setReservedCount(cabinCounter.getReservedCount() + 1);
						}
					}
				}

				cabinCounterList.add(cabinCounter);
			}
		}
		
		return cabinCounterList;
	}

	/**
	 * To convert from DTOSegment in com.hna.mars.service.order.dto package to DTOSegment in com.hna.mars.service.flight.dto package
	 * 
	 * @param segment
	 * @return
	 */
	public static DTOSegment convertToFlightSegment(
			com.myway.dto.order.DTOSegment segment) {
		DTOSegment fltSegment = new DTOSegment();

		fltSegment.setCarrier(segment.getAirlineCode());
		// Get flight number without airline code
		String fltNo = FlightNoUtils.getFlightNo(segment.getFlightNo());
		fltSegment.setFlightNo(fltNo);
		fltSegment.setDepartureTime(segment.getDepTime());
		fltSegment.setOriginCity(segment.getDepCode());
		fltSegment.setDestinationCity(segment.getArrCode());
		fltSegment.setAircraftStyle(segment.getPlaneType());

		return fltSegment;
	}
	
	/**
	 * To convert from DTOSegment in com.hna.mars.service.flight.dto package to DTOSegment in com.hna.mars.service.order.dto package
	 * 
	 * @param segment
	 * @return
	 */
	public static com.myway.dto.order.DTOSegment convertToOrderSegment(
			DTOSegment segment) {
		com.myway.dto.order.DTOSegment orderSegment = new com.myway.dto.order.DTOSegment();

		orderSegment.setAirlineCode(segment.getCarrier());
		orderSegment.setFlightNo(segment.getFlightNo());
		orderSegment.setDepTime(segment.getDepartureTime());
		orderSegment.setDepCode(segment.getOriginCity());
		orderSegment.setArrCode(segment.getDestinationCity());
		orderSegment.setPlaneType(segment.getAircraftStyle());

		return orderSegment;
	}
	
	/**
	 * Return true if the given segments is same.
	 * 判断两个航段是否一样
	 * 
	 * @param segment1
	 * @param segment2
	 * @return
	 */
	public static boolean isSameSegment(final com.myway.dto.order.DTOSegment segment1, final com.myway.dto.order.DTOSegment segment2) {
		return (segment1.getFlightNo().equals(segment2.getFlightNo()) 
				&& segment1.getDepCode().equals(segment2.getDepCode())
				&& segment1.getArrCode().equals(segment2.getArrCode()) 
				&& segment1.getCabinClass().equals(segment2.getCabinClass()) 
				&& DateUtils.isSameFlightTime(segment1.getDepTime(), segment2.getDepTime()));
	}
	public static boolean isSameSegment(final FlySegmentVo segment1, final FlySegmentVo segment2) {
		return (segment1.getFlightNo().equals(segment2.getFlightNo())
				&& segment1.getDepCode().equals(segment2.getDepCode())
				&& segment1.getArrCode().equals(segment2.getArrCode())
				&& segment1.getCabinClass().equals(segment2.getCabinClass())
				&& DateUtils.isSameFlightTime(segment1.getDepTime(), segment2.getDepTime()));
	}

	/**
	 * @名称：isSameSegmentForExtbuy 
	 * @描述：匹配补购航段是否一样 
	 * @param segment1
	 * @param segment2
	 * @return
	*/
	public static boolean isSameSegmentForExtbuy(final com.myway.dto.order.DTOSegment segment1, final com.myway.dto.order.DTOSegment segment2) {
		return (segment1.getFlightNo().equals(segment2.getFlightNo()) 
				&& segment1.getDepCode().equals(segment2.getDepCode())
				&& segment1.getArrCode().equals(segment2.getArrCode()) 
//				&& segment1.getCabinClass().equals(segment2.getCabinClass()) 
				&& DateUtils.isSameFlightTime(segment1.getDepTime(), segment2.getDepTime()));
	}
	
	/**
	 * Get distinct segments from the list of passenger segments.
	 * 从旅客航段列表中获取不重复的航段集合
	 * @param paxSegList
	 * @return
	 */
	public static List<com.myway.dto.order.DTOSegment> getDistinctSegments(final List<DTOPaxSegment> paxSegList) {
		List<com.myway.dto.order.DTOSegment> distinctSegments = new ArrayList<com.myway.dto.order.DTOSegment>();
		for (DTOPaxSegment ps : paxSegList) {
			boolean found = false;
			
			// Check whether the segment has been added to distinct segment list
			for (com.myway.dto.order.DTOSegment s : distinctSegments) {
				if (isSameSegment(ps, s)) {
					// Segment is added
					found = true;
					// Skip to next passenger segment
					break;
				}
			}
			
			if (!found) {
				// Segment is not added yet. Construct new segment and copy the properties from passenger segment.
				com.myway.dto.order.DTOSegment s = new com.myway.dto.order.DTOSegment();
				try {
					BeanUtils.copyProperties(s, ps);
				} catch (IllegalAccessException e) {
					throw new RuntimeException("Error copying properties of : " + ps.getClass().getName(), e);
				} catch (InvocationTargetException e) {
					throw new RuntimeException("Error copying properties of : " + ps.getClass().getName(), e);
				}
				distinctSegments.add(s);
			}
		}
		
		return distinctSegments;
	}
	
	/**
	 * Filter the segment list by inventory. All segments in the list which are not from the given inventory will be removed from
	 * the list.
	 * 
	 * @param segList List of segments to be filtered.
	 * @param inventory Inventory
	 */
	public static void filterSegmentByInventory(List<com.myway.dto.order.DTOSegment> segList, final Inventory inventory) {
		for (com.myway.dto.order.DTOSegment s : segList) {
			if (inventory != s.getInventory()) {
				segList.remove(s);
			}
		}
	}
	
	/**
	 * A utility method to retrieve Segment entity which the flight number and departure time is same as the DTOPaxSegment
	 * 从航段集合中获取与某个旅客航段相同的航段
	 * @param paxSeg
	 * @param segments
	 * @return
	 */
	public static FlySegmentVo getMatchingSegment(final FlySegmentVo paxSeg, final List<FlySegmentVo> segments) {
		for (FlySegmentVo s : segments) {
			if (isSameSegment(paxSeg, s)) {
				return s;
			}
		}
		return null;
	}
}
